﻿using System;
using System.Data;
using System.Configuration;

using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.ComponentModel;
using System.Text;
using System.Collections.Generic;

namespace TA.Turbo.Controls
{
	/// <summary>
	/// An event which can be processed on the client and on the server.
	/// </summary>
	public class ServerEvent<T> : BaseServerEvent, IServerEvent<T>
		where T : EventArgs
	{
		#region PUBLIC
		#region INIT
		/// <summary>
		/// Ctor.
		/// </summary>
		public ServerEvent()			//: this(new ControlTransferOptions(), new ControlTransferOptions())
		{
		}
		#endregion
		#region PROPS
		/// <summary>
		/// The server-side handler delegate.
		/// </summary>
		public event EventHandler<T> Server;
		//{
		//  add
		//  {
		//  }
		//  remove
		//  {
		//  }
		//}
		/// <summary>
		/// Gets true if any handlers attached to the server-side delegate.
		/// </summary>
		public override bool Active
		{
			get
			{
				return this.Server != null;
			}
		}
		/// <summary>
		/// Gets the client-side scenario ID for this event.
		/// </summary>
		[Browsable(false)]
		public string PreparedPostScenarioId
		{
			get
			{
				if (this.PostScenario == null)
					return null;
				return this.PostScenario.ClientID;
			}
		}
		#endregion
		#region METHODS
		public void CopyFrom(ServerEvent<T> source)
		{
			base.CopyFrom(source);

			this.Server = source.Server;
		}
		/// <summary>
		/// Raises the event.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		public void Raise(object sender, T e)
		{
			if (Server != null)
				Server(sender, e);
		}
		/// <summary>
		/// Adds attributes for this event to HTML output.
		/// </summary>
		/// <param name="writer"></param>
		public override void AddAttributes(HtmlTextWriter writer)
		{
			base.AddAttributes(writer);
			if (/*this.Active && */this.PostScenario != null)
				writer.AddAttribute(this._name + "-Server", this.PreparedPostScenarioId);
		}
		/// <summary>
		/// If no scenario set, sets the specified scenario, otherwise merges the specified scenario with the existing scenario.
		/// </summary>
		/// <param name="scenario"></param>
		public void EnsureScenario(PostScenario scenario)
		{
			if (this._c.get_IsDesignMode()) return;

			PostScenario ps = this.PostScenario;
			if (ps == null)
			{
				scenario.ID = this._c.ClientID + TControl.ClientIdSeparator + this._name;
				this._c.TPage.Scenarios.Add(scenario);
				this.PostScenario = scenario;
				return;
			}
			ps.Ensure(scenario);
		}
		#endregion
		#endregion

		#region INTERNAL
		#region VARS
		#endregion
		#region METHODS
		/// <summary>
		/// Returns the client script which needs to be executed in order to raise this event.
		/// </summary>
		/// <param name="argument"></param>
		/// <returns></returns>
		protected override string DoGetEventScript(object argument)
		{
			if (this.Active)
			{
				string script = this.GetEventClientScript(argument);
				if (!string.IsNullOrEmpty(script))
					script = string.Format("function() {{ {0} }}", script);
				else
					script = "null";
				
				return 
					string.Format(
						"return $SimpleControl.Raise{0}(event, {1}, {2}, {3});"
						, this._name
						, script
						, this.PostScenario == null ? "null" : "\"" + this.PostScenario.ClientID + "\""
						, this.SerializeArgument(argument)
					);
			}
			return base.DoGetEventScript(argument);
		}
		#endregion
		#endregion
	}
}